package com.duojuhe.coremodule.tracking.service.impl;

import com.duojuhe.cache.SystemDictCache;
import com.duojuhe.common.annotation.DataScopeFilter;
import com.duojuhe.common.bean.UserTokenInfoVo;
import com.duojuhe.common.constant.DataScopeConstants;
import com.duojuhe.common.enums.SystemEnum;
import com.duojuhe.common.exception.base.DuoJuHeException;
import com.duojuhe.common.result.ErrorCodes;
import com.duojuhe.common.result.PageResult;
import com.duojuhe.common.result.ServiceResult;
import com.duojuhe.common.utils.idgenerator.UUIDUtils;
import com.duojuhe.common.utils.page.PageHelperUtil;
import com.duojuhe.coremodule.BaseService;
import com.duojuhe.coremodule.system.entity.SystemDict;
import com.duojuhe.coremodule.tracking.entity.TrackingCode;
import com.duojuhe.coremodule.tracking.entity.TrackingProduct;
import com.duojuhe.coremodule.tracking.entity.TrackingProductCategory;
import com.duojuhe.coremodule.tracking.mapper.TrackingCodeMapper;
import com.duojuhe.coremodule.tracking.mapper.TrackingProductCategoryMapper;
import com.duojuhe.coremodule.tracking.mapper.TrackingProductMapper;
import com.duojuhe.coremodule.tracking.pojo.dto.trackingproduct.*;
import com.duojuhe.coremodule.tracking.service.TrackingProductService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class TrackingProductServiceImpl extends BaseService implements TrackingProductService {
    @Resource
    private SystemDictCache systemDictCache;
    @Resource
    private TrackingProductCategoryMapper trackingProductCategoryMapper;
    @Resource
    private TrackingCodeMapper trackingCodeMapper;
    @Resource
    private TrackingProductMapper trackingProductMapper;

    /**
     * 【查询所有产品】产品管理
     * @param req
     * @return
     */
    @DataScopeFilter
    @Override
    public ServiceResult<PageResult<List<QueryTrackingProductPageRes>>> queryTrackingProductPageResList(QueryTrackingProductPageReq req) {
        PageHelperUtil.orderByAndStartPage(req, "createTime desc, productId desc");
        List<QueryTrackingProductPageRes> list = trackingProductMapper.queryTrackingProductPageResList(req);
        for (QueryTrackingProductPageRes res:list){
            SystemDict dictStatus = systemDictCache.getSystemDictByDictCode(res.getStatusCode());
            res.setStatusName(dictStatus.getDictName());
            res.setStatusColor(dictStatus.getDictColor());
        }
        return PageHelperUtil.returnServiceResult(req, list);
    }

    /**
     * 【查询所有产品】供前端选择产品
     * @param req
     * @return
     */
    @DataScopeFilter(dataScope = DataScopeConstants.TENANT_ALL_DATA)
    @Override
    public ServiceResult<PageResult<List<QueryTrackingProductPageRes>>> querySelectTrackingProductPageResList(QueryTrackingProductPageReq req) {
        PageHelperUtil.orderByAndStartPage(req, "createTime desc, productId desc");
        List<QueryTrackingProductPageRes> list = trackingProductMapper.queryTrackingProductPageResList(req);
        for (QueryTrackingProductPageRes res:list){
            SystemDict dictStatus = systemDictCache.getSystemDictByDictCode(res.getStatusCode());
            res.setStatusName(dictStatus.getDictName());
            res.setStatusColor(dictStatus.getDictColor());
        }
        return PageHelperUtil.returnServiceResult(req, list);
    }

    /**
     * 【保存】产品
     * @param req
     * @return
     */
    @Override
    public ServiceResult saveTrackingProduct(SaveTrackingProductReq req) {
        //当前登录用户
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //租户id
        String tenantId = userTokenInfoVo.getTenantId();
        //检查分类
        checkProductCategoryId(req.getProductCategoryId(),tenantId);
        //检查产品名称
        checkProductName(req.getProductName(),tenantId);
        //检查产品编码
        checkProductCode(req.getProductCode(),tenantId);
        //检查产品条码
        checkProductBarcode(req.getProductBarcode(),tenantId);
        //产品ID
        String productId = UUIDUtils.getUUID32();
        //当前时间
        Date date = new Date();
        TrackingProduct product = new TrackingProduct();
        product.setProductId(productId);
        product.setProductCategoryId(req.getProductCategoryId());
        product.setProductNumber(UUIDUtils.getSequenceNo());
        product.setProductName(req.getProductName());
        product.setProductBarcode(req.getProductBarcode());
        product.setProductCode(req.getProductCode());
        product.setProductImg(req.getProductImg());
        product.setStatusCode(req.getStatusCode());
        product.setRemark(req.getRemark());
        product.setDescription(req.getDescription());
        product.setCreateTime(date);
        product.setUpdateTime(date);
        product.setSort(req.getSort());
        product.setCreateUserId(userTokenInfoVo.getUserId());
        product.setUpdateUserId(userTokenInfoVo.getUserId());
        product.setCreateDeptId(userTokenInfoVo.getCreateDeptId());
        product.setTenantId(userTokenInfoVo.getTenantId());
        trackingProductMapper.insertSelective(product);
        return ServiceResult.ok(productId);
    }


    /**
     * 【修改】产品
     * @param req
     * @return
     */
    @Override
    public ServiceResult updateTrackingProduct(UpdateTrackingProductReq req) {
        //产品ID
        String productId = req.getProductId();
        TrackingProduct productOld = trackingProductMapper.selectByPrimaryKey(productId);
        if (productOld==null){
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //租户id
        String tenantId = productOld.getTenantId();
        //检查分类
        checkProductCategoryId(req.getProductCategoryId(),tenantId);
        //检查产品名称
        if (!StringUtils.equals(req.getProductName(),productOld.getProductName())){
            checkProductName(req.getProductName(),tenantId);
        }
        //检查产品编码
        if (!StringUtils.equals(req.getProductCode(),productOld.getProductCode())){
            checkProductCode(req.getProductCode(),tenantId);
        }
        //检查产品条码
        if (!StringUtils.equals(req.getProductBarcode(),productOld.getProductBarcode())){
            checkProductBarcode(req.getProductBarcode(),tenantId);
        }
        //当前登录用户
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //当前时间
        Date date = new Date();
        TrackingProduct product = new TrackingProduct();
        product.setProductId(productId);
        product.setProductCategoryId(req.getProductCategoryId());
        product.setProductName(req.getProductName());
        product.setProductBarcode(req.getProductBarcode());
        product.setProductCode(req.getProductCode());
        product.setProductImg(req.getProductImg());
        product.setStatusCode(req.getStatusCode());
        product.setRemark(req.getRemark());
        product.setDescription(req.getDescription());
        product.setUpdateTime(date);
        product.setSort(req.getSort());
        product.setUpdateUserId(userTokenInfoVo.getUserId());
        trackingProductMapper.updateByPrimaryKeySelective(product);
        return ServiceResult.ok(productId);
    }

    /**
     * 【删除】根据产品ID删除产品，注意一次仅能删除一个产品，存在绑定关系的则不能删除
     * @param req
     * @return
     */
    @Override
    public ServiceResult deleteTrackingProductByProductId(TrackingProductIdReq req) {
        //产品ID
        String productId = req.getProductId();
        TrackingProduct productOld = trackingProductMapper.selectByPrimaryKey(productId);
        if (productOld==null){
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //检查是否关联了 防伪码
        checkRelationTrackingCode(productId);
        //产品删除
        trackingProductMapper.deleteByPrimaryKey(productId);
        return ServiceResult.ok(productId);
    }


    /**
     * 【私有方法，辅助其他接口方法使用】 根据产品id查询是否关联了防伪码
     */
    private void checkRelationTrackingCode(String productId) {
        if (StringUtils.isBlank(productId)){
            throw new DuoJuHeException(ErrorCodes.TRACKING_PRODUCT_RELATION_TRACKING_CODE_NOT_DELETE);
        }
        Example example = new Example(TrackingCode.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("productId", productId);
        if(trackingCodeMapper.selectByExample(example).size()>0){
            throw new DuoJuHeException(ErrorCodes.TRACKING_PRODUCT_RELATION_TRACKING_CODE_NOT_DELETE);
        }
    }

    /**
     * 【私有方法，辅助其他接口方法使用】 检查产品分类是否存在
     */
    private void checkProductCategoryId(String categoryId,String tenantId) {
        if (StringUtils.isBlank(categoryId)||StringUtils.isBlank(tenantId)){
            throw new DuoJuHeException(ErrorCodes.TRACKING_PRODUCT_CATEGORY_NOT_EXIST);
        }
        TrackingProductCategory productCategory = trackingProductCategoryMapper.selectByPrimaryKey(categoryId);
        if(productCategory==null || !SystemEnum.STATUS.NORMAL.getKey().equals(productCategory.getStatusCode())){
            throw new DuoJuHeException(ErrorCodes.TRACKING_PRODUCT_CATEGORY_NOT_EXIST);
        }
        if (!tenantId.equals(productCategory.getTenantId())){
            throw new DuoJuHeException(ErrorCodes.TRACKING_PRODUCT_CATEGORY_NOT_EXIST);
        }
    }

    /**
     * 【私有方法，辅助其他接口方法使用】 检查当前租户下面产品名称是否已经存在
     */
    private void checkProductName(String productName,String tenantId) {
        if (StringUtils.isBlank(productName)||StringUtils.isBlank(tenantId)){
            throw new DuoJuHeException(ErrorCodes.TRACKING_PRODUCT_NAME_EXIST);
        }
        Example example = new Example(TrackingProduct.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("productName", productName);
        criteria.andEqualTo("tenantId", tenantId);
        if(trackingProductMapper.selectByExample(example).size()>0){
            throw new DuoJuHeException(ErrorCodes.TRACKING_PRODUCT_NAME_EXIST);
        }
    }

    /**
     * 【私有方法，辅助其他接口方法使用】 检查当前租户下面产品条码是否已经存在
     */
    private void checkProductBarcode(String productBarcode,String tenantId) {
        if (StringUtils.isBlank(productBarcode)||StringUtils.isBlank(tenantId)){
            throw new DuoJuHeException(ErrorCodes.TRACKING_PRODUCT_BARCODE_EXIST);
        }
        Example example = new Example(TrackingProduct.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("productBarcode", productBarcode);
        criteria.andEqualTo("tenantId", tenantId);
        if(trackingProductMapper.selectByExample(example).size()>0){
            throw new DuoJuHeException(ErrorCodes.TRACKING_PRODUCT_BARCODE_EXIST);
        }
    }

    /**
     * 【私有方法，辅助其他接口方法使用】 检查当前租户下面产品编码是否已经存在
     */
    private void checkProductCode(String productCode,String tenantId) {
        if (StringUtils.isBlank(productCode)||StringUtils.isBlank(tenantId)){
            throw new DuoJuHeException(ErrorCodes.TRACKING_PRODUCT_CODE_EXIST);
        }
        Example example = new Example(TrackingProduct.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("productCode", productCode);
        criteria.andEqualTo("tenantId", tenantId);
        if(trackingProductMapper.selectByExample(example).size()>0){
            throw new DuoJuHeException(ErrorCodes.TRACKING_PRODUCT_CODE_EXIST);
        }
    }
}
